package com.baizhi.service.impl;

import com.baizhi.dao.BzAdminMapper;
import com.baizhi.entity.BzAdmin;
import com.baizhi.service.BzRoleService;
import com.baizhi.service.IBzAdminService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class BzAdminServiceImpl extends ServiceImpl<BzAdminMapper, BzAdmin> implements IBzAdminService {
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private BzRoleService roleService;
    /**
     * 参数是用户浏览器输入的用户名
     *
     * 将bzAdmin改造为UserDetails的实现类
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        /**
         * 验证码校验
         *
         * session 验证码
         * 请求中携带的验证码
         */
        String requestCode = request.getParameter("code");
        String sessionCode = request.getSession().getAttribute("code") + "";
        if (requestCode==null || !requestCode.equals(sessionCode)) {
            /**
             * 方案一 Request作用域
             * 方案二 Session作用域
             * 方案三 ThreadLocal 是什么？【面试重点】
             *
             * 将信息 验证码不正确 放入ThreadLocal  在AdminController中可以取出来
             */

            throw new UsernameNotFoundException("验证码不正确");
        }

//        根据用户名查询数据库 获取用户信息
        BzAdmin admin = this.getOne(new QueryWrapper<BzAdmin>().eq("username", username));
        if (admin == null){

            throw new UsernameNotFoundException("用户名或者密码不正确");

        }

        /**
         * 用户存在 一个用户一定有角色和权限
         *
         * 查询用户的授权信息 封装到BZAdmin对象中
         *
         * 角色和权限都封装到一个属性authorities 一个集合中 怎么区分角色和权限？
         * 角色需要增加前缀 ROLE_
         */
        Set<String> roles = roleService.getRolesByUsername(username);
//        角色名加前缀
        roles = roles.stream().map(role->{
            return "ROLE_"+role;
        }).collect(Collectors.toSet());
        Set<String> permissions = roleService.getPermissionsByUsername(username);

//        合并两个集合
        roles.addAll(permissions);

//        所有String的角色权限信息 封装到 SimpleGrantedAuthority
        List<GrantedAuthority> authorityList = roles.stream().map(role -> {
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role);
            return authority;
        }).collect(Collectors.toList());

        admin.setAuthorities(authorityList);

        return admin;
    }

    @Override
    public Boolean addAdmin(String username, String password) {
        /**
         * 明文加密
         */
        String encode = bCryptPasswordEncoder.encode(password);

        /**
         * 密文注册到数据库
         *
         */
        BzAdmin admin = new BzAdmin();
        admin.setUsername(username);
        admin.setPassword(encode);
        admin.setStatus(0);
        return this.save(admin);
    }
}
